package com.dream.common.utils.pickutils;


import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;

public class NumberUtil {
    /**
     * 分转成元 保留两位小数
     *
     * @param money
     * @return
     */
    public static double getMoneyYuanDouble(int money) {
        DecimalFormat df = new DecimalFormat("######0.00");
        double doubleMoney = money / 100.0;
        return Double.parseDouble(df.format(doubleMoney));
    }

    /**
     * 分转成元 保留两位小数
     *
     * @param money
     * @return
     */
    public static double getMoneyYuanDouble(double money) {
        DecimalFormat df = new DecimalFormat("######0.00");
        double doubleMoney = money / 100.0;
        return Double.parseDouble(df.format(doubleMoney));
    }

    /**
     * 分转成元 保留两位小数
     *
     * @param money
     * @return
     */
    public static String getMoneyYuanString(int money) {
        DecimalFormat df = new DecimalFormat("######0.00");
        double doubleMoney = money / 100.0;
        return df.format(doubleMoney);
    }

    /**
     * 分转成元 保留两位小数
     *
     * @param money
     * @return
     */
    public static String getMoneyYuanString(String money) {
        if (money == null || money.equals("")) {
            return "0";
        }
        double intMoney = Double.parseDouble(money);
        DecimalFormat df = new DecimalFormat("######0.00");
        double doubleMoney = intMoney / 100.0;
        return df.format(doubleMoney);
    }


    /**
     * 提供精确的小数位四舍五入处理,舍入模式采用ROUND_HALF_EVEN
     *
     * @param v     需要四舍五入的数字
     * @param scale 小数点后保留几位
     * @return 四舍五入后的结果，以字符串格式返回
     */
    public static String round(String v, int scale) {
        return round(v, scale, BigDecimal.ROUND_HALF_EVEN);
    }

    /**
     * 提供精确的小数位四舍五入处理
     *
     * @param v          需要四舍五入的数字
     * @param scale      小数点后保留几位
     * @param round_mode 指定的舍入模式
     * @return 四舍五入后的结果，以字符串格式返回
     */
    public static String round(String v, int scale, int round_mode) {
        if (scale < 0) {
            throw new IllegalArgumentException(
                    "The scale must be a positive integer or zero");
        }
        BigDecimal b = new BigDecimal(v);
        return b.setScale(scale, round_mode).toString();
    }

    // 默认除法运算精度
    private static final int DEFAULT_DIV_SCALE = 10;

    /**
     * 提供精确的加法运算。
     *
     * @param v1
     * @param v2
     * @return 两个参数的和
     */
    public static double add(double v1, double v2) {
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        return b1.add(b2).doubleValue();
    }

    /**
     * 提供精确的加法运算。
     *
     * @param doubleArr
     * @return 多个参数的和
     */
    public static double add(double... doubleArr) {
        BigDecimal allBD = new BigDecimal(Double.toString(0));
        for (double mDouble : doubleArr) {
            BigDecimal bdMoney = new BigDecimal(Double.toString(mDouble));
            allBD = allBD.add(bdMoney);
        }
        return allBD.doubleValue();
    }

    /**
     * 提供精确的加法运算
     *
     * @param v1
     * @param v2
     * @return 两个参数数学加和，以字符串格式返回
     */
    public static String add(String v1, String v2) {
        if (v1 == null || "".equals(v1)) {
            v1 = "0";
        }
        if (v2 == null || "".equals(v2)) {
            v2 = "0";
        }
        BigDecimal b1 = new BigDecimal(v1);
        BigDecimal b2 = new BigDecimal(v2);
        return b1.add(b2).toString();
    }

    /**
     * 提供精确的减法运算。
     *
     * @param v1
     * @param v2
     * @return 两个参数的差
     */
    public static double subtract(double v1, double v2) {
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        return b1.subtract(b2).doubleValue();
    }

    /**
     * 提供精确的减法运算,一减多。
     *
     * @param v1
     * @param doubleArr
     * @return 多个参数的和
     */
    public static double subtract(double v1, double... doubleArr) {
        BigDecimal result = new BigDecimal(Double.toString(v1));
        for (double mDouble : doubleArr) {
            BigDecimal bdMoney = new BigDecimal(Double.toString(mDouble));
            result = result.subtract(bdMoney);
        }
        return result.doubleValue();
    }

    /**
     * 提供精确的减法运算。
     *
     * @param v1
     * @param v2
     * @return 两个参数的差
     */
    public static int subtract(int v1, int v2) {
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        return b1.subtract(b2).intValue();
    }

    /**
     * 提供精确的减法运算
     *
     * @param v1
     * @param v2
     * @return 两个参数数学差，以字符串格式返回
     */
    public static String subtract(String v1, String v2) {
        if (StringUtils.isEmpty(v1)) {
            v1 = "0";
        }
        if (StringUtils.isEmpty(v2)) {
            v2 = "0";
        }
        BigDecimal b1 = new BigDecimal(v1);
        BigDecimal b2 = new BigDecimal(v2);
        return b1.subtract(b2).toString();
    }

    /**
     * 提供精确的乘法运算。
     *
     * @param v1
     * @param v2
     * @return 两个参数的积
     */
    public static double multiply(double v1, double v2) {
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        return b1.multiply(b2).doubleValue();
    }

    /**
     * 提供精确的乘法运算
     *
     * @param v1
     * @param v2
     * @return 两个参数的数学积，以字符串格式返回
     */
    public static String multiply(String v1, String v2) {
        BigDecimal b1 = new BigDecimal(v1);
        BigDecimal b2 = new BigDecimal(v2);
        DecimalFormat df = new DecimalFormat("######0.00");

        return df.format(b1.multiply(b2));
    }

    /**
     * 提供（相对）精确的除法运算，当发生除不尽的情况时，精确到 小数点以后10位，以后的数字四舍五入,舍入模式采用ROUND_HALF_EVEN
     *
     * @param v1
     * @param v2
     * @return 两个参数的商
     */
    public static double divide(double v1, double v2) {
        return divide(v1, v2, DEFAULT_DIV_SCALE);
    }

    /**
     * 提供（相对）精确的除法运算。当发生除不尽的情况时，由scale参数指 定精度，以后的数字四舍五入。舍入模式采用ROUND_HALF_EVEN
     *
     * @param v1
     * @param v2
     * @param scale 表示需要精确到小数点以后几位。
     * @return 两个参数的商
     */
    public static double divide(double v1, double v2, int scale) {
        return divide(v1, v2, scale, BigDecimal.ROUND_HALF_EVEN);
    }

    /**
     * 提供（相对）精确的除法运算。当发生除不尽的情况时，由scale参数指 定精度，以后的数字四舍五入。舍入模式采用用户指定舍入模式
     *
     * @param v1
     * @param v2
     * @param scale      表示需要精确到小数点以后几位
     * @param round_mode 表示用户指定的舍入模式
     * @return 两个参数的商
     */
    public static double divide(double v1, double v2, int scale, int round_mode) {
        if (scale < 0) {
            throw new IllegalArgumentException(
                    "The scale must be a positive integer or zero");
        }
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        return b1.divide(b2, scale, round_mode).doubleValue();
    }

    /**
     * 提供（相对）精确的除法运算，当发生除不尽的情况时，精确到 小数点以后10位，以后的数字四舍五入,舍入模式采用ROUND_HALF_EVEN
     *
     * @param v1
     * @param v2
     * @return 两个参数的商，以字符串格式返回
     */
    public static String divide(String v1, String v2) {
        return divide(v1, v2, DEFAULT_DIV_SCALE);
    }

    /**
     * 提供（相对）精确的除法运算。当发生除不尽的情况时，由scale参数指 定精度，以后的数字四舍五入。舍入模式采用ROUND_HALF_EVEN
     *
     * @param v1
     * @param v2
     * @param scale 表示需要精确到小数点以后几位
     * @return 两个参数的商，以字符串格式返回
     */
    public static String divide(String v1, String v2, int scale) {
        String number = divide(v1, v2, DEFAULT_DIV_SCALE, BigDecimal.ROUND_HALF_EVEN);
        return round(number, scale);
    }

    /**
     * 提供（相对）精确的除法运算。当发生除不尽的情况时，由scale参数指 定精度，以后的数字四舍五入。舍入模式采用用户指定舍入模式
     *
     * @param v1
     * @param v2
     * @param scale      表示需要精确到小数点以后几位
     * @param round_mode 表示用户指定的舍入模式
     * @return 两个参数的商，以字符串格式返回
     */
    public static String divide(String v1, String v2, int scale, int round_mode) {
        if (scale < 0) {
            throw new IllegalArgumentException(
                    "The scale must be a positive integer or zero");
        }
        BigDecimal b1 = new BigDecimal(v1);
        BigDecimal b2 = new BigDecimal(v2);
        return b1.divide(b2, scale, round_mode).toString();
    }

    /**
     * 提供精确的小数位四舍五入处理,舍入模式采用ROUND_HALF_EVEN
     *
     * @param v     需要四舍五入的数字
     * @param scale 小数点后保留几位
     * @return 四舍五入后的结果
     */
    public static double round(double v, int scale) {
        return round(v, scale, BigDecimal.ROUND_HALF_EVEN);
    }

    /**
     * 提供精确的小数位四舍五入处理
     *
     * @param v          需要四舍五入的数字
     * @param scale      小数点后保留几位
     * @param round_mode 指定的舍入模式
     * @return 四舍五入后的结果
     */
    public static double round(double v, int scale, int round_mode) {
        if (scale < 0) {
            throw new IllegalArgumentException(
                    "The scale must be a positive integer or zero");
        }
        BigDecimal b = new BigDecimal(Double.toString(v));
        return b.setScale(scale, round_mode).doubleValue();
    }

    /**
     * 判断一个字符串是不是数字
     *
     * @param thunder
     * @return
     */
    public static boolean stringIsNumber(String thunder) {
        if (StringUtils.isEmpty(thunder)) {
            return false;
        }
        try {
            Integer.parseInt(thunder);
            return true;
        } catch (Exception e) {
            return false;
        }

    }

    public static List<String> getBeishuList() {
        List<String> beishuList = new ArrayList<>();
        double beishu = 0.0;
        for (int i = 0; i < 40; i++) {
            beishuList.add(beishu + "");
            beishu = Double.parseDouble(NumberUtil.add(beishu + "", "0.5"));
        }
        beishu = 20.0;
        for (int i = 0; i < 81; i++) {
            beishuList.add(beishu + "");
            beishu = Double.parseDouble(NumberUtil.add(beishu + "", "1"));
        }
        beishu = 0.00;
        for (int i = 0; i < 100; i++) {
            beishuList.add(beishu + "");
            beishu = Double.parseDouble(NumberUtil.add(beishu + "", "0.1"));
        }
        return beishuList;
    }

    public static int getMin(Integer... integers) {
        int mMin = 100;
        for (Integer min : integers) {
            if (min < mMin) {
                mMin = min;
            }
        }
        return mMin;
    }

    public static List<String> getFloors(int count) {
        List<String> floors = new ArrayList<>();
        for (int floor = 1; floor < count + 1; floor++) {
            floors.add(floor + "");
        }
        return floors;
    }

    public static String getDigit(String str) {
        str = str.trim();
        char[] strChar = str.toCharArray();
        //去除前面的非数字
        for (int i = 0; i < strChar.length; i++) {
            if (!Character.isDigit(strChar[i])) {
                str.replace(strChar[i] + "", "");
            } else {
                break;
            }
        }
        //去除后面的非数字
        for (int i = strChar.length; i > 0; i--) {
            if (!Character.isDigit(strChar[i - 1])) {
                str.replace(strChar[i - 1] + "", "");
            } else {
                break;
            }
        }
        return str;
    }

    /**
     * 是否是纯数字
     *
     * @return
     */
    public static boolean isDigit(String str) {
        str = str.trim();
//        char[] strChar = str.toCharArray();
//        //去除前面的非数字
//        for (int i = 0; i < strChar.length; i++) {
//            if (!Character.isDigit(strChar[i])) {
//                str.replace(strChar[i] + "", "");
//            } else {
//                break;
//            }
//        }
//        //去除后面的非数字
//        for (int i = strChar.length; i > 0; i--) {
//            if (!Character.isDigit(strChar[i - 1])) {
//                str.replace(strChar[i - 1] + "", "");
//            } else {
//                break;
//            }
//        }
        //判断是否为纯数字
        for (char c : str.toCharArray()) {
            if (!Character.isDigit(c)) {
                return false;
            }
        }
        return true;
    }


    public static void main(String[] args) {
//        Log.e("TIME", "time: " + System.currentTimeMillis());

    }
}
